# -*- coding:utf-8 -*- 

import os, sys
import pdb
import logging
import logging.config
from datetime import date
from threadlocal import get_threadlocal
from _log_json_handler import (get_console_handler,
                               get_error_handler,
                               get_info_handler)
import sc_logging_conf as CONFIG
logging.config.dictConfig(CONFIG.SC_LOGGING_CONF)

__all__ = ['get_logger', 'get_json_logger']

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0


# caller stack frame.
#
if hasattr(sys, 'frozen'): #support for py2exe
    _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
elif __file__[-4:].lower() in ['.pyc', '.pyo']:
    _srcfile = __file__[:-4] + '.py'
else:
    _srcfile = __file__
_srcfile = os.path.normcase(_srcfile)



class SCLogger(logging.Logger):
    def __init__(self, name, level=logging.NOTSET):
        logging.Logger.__init__(self, name, level)
        self.sc_format = "[%(asctime)s] [%(levelname)s] [%(threadName)s:%(thread)d] [%(filename)s:%(lineno)d] [%(scid)s] [%(ip)s] - %(message)s"
        self.path = "py_log/"
        self.assure_path_exists(self.path)

    def _log(self, level, msg, args, exc_info=None, extra=None):
        """
        Low-level logging routine which creates a LogRecord and then calls
        all the handlers of this logger to handle the record.
        """
        if _srcfile:
            #IronPython doesn't track Python frames, so findCaller raises an
            #exception on some versions of IronPython. We trap it here so that
            #IronPython can use logging.
            try:
                fn, lno, func = self.findCaller()
            except ValueError:
                fn, lno, func = "(unknown file)", 0, "(unknown function)"
        else:
            fn, lno, func = "(unknown file)", 0, "(unknown function)"
        if exc_info:
            if not isinstance(exc_info, tuple):
                exc_info = sys.exc_info()

        # 对应新增scid和ip到SC_FORMAT中(_sc_logger.py)
        extra = extra if extra else {'scid':'', 'ip':''}

        record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
        self.handle(record)

    def request(self, msg, *args, **kwargs):
        self.info(":".join(["@Request", msg]), *args, **kwargs)

    def parse(self, msg, *args, **kwargs):
        self.info(":".join(["@Parse", msg]), *args, **kwargs)

    def save(self, msg, *args, **kwargs):
        self.info(":".join(["@Save", msg]), *args, **kwargs)

    def assure_path_exists(self, path):
        dir = os.path.dirname(path)
        if not os.path.exists(dir):
            os.makedirs(dir)

    def get_console_handler(self):
        console_format = logging.Formatter(self.sc_format)
        console_handler = logging.StreamHandler(sys.stdout)
        console_handler.setFormatter(console_format)
        return console_handler

    def get_file_handler(self):
        file_name = self.path + "sc-" + date.today().isoformat() + ".log"
        file_format = logging.Formatter(self.sc_format)
        file_handler = logging.handlers.RotatingFileHandler(file_name, maxBytes=10*1024*1024, backupCount=20)
        file_handler.setFormatter(file_format)
        return file_handler


def get_logger(filename="sc"):
    logger = SCLogger('sc')
    # console log
    console_handler = logger.get_console_handler()
    logger.addHandler(console_handler)
    # file log
    file_handler = logger.get_file_handler()
    logger.addHandler(file_handler)
    # log level
    logger.setLevel(logging.DEBUG)
    return logger


def get_json_logger(filename):
    logger = logging.getLogger(filename)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(get_console_handler())
    logger.addHandler(get_info_handler())
    logger.addHandler(get_error_handler())
    return logger
